<?php

namespace core;

class HtmlElement extends \core\Html
{
	/**
	 * Enter description here...
	 *
	 * @var	object	SimpleXmlElement
	 */
	public $element;

	/**
	 * Sets up SimpleXml element
	 *
	 * @param	string	$tag
	 */
	public function __construct($tag = "", $content = "")
	{
		//Custom element
		if (is_a($tag, "\SimpleXmlElement"))
		{
			$xml = $tag;
		}
		else
		{
			if (empty($tag))
			{
				die("Tag name must be provided");
			}

			$xml = simplexml_load_string("<$tag>$content</$tag>");
		}

		$this->SetElement($xml);
	}

	/**
	 * Returns SimpleXml elment
	 *
	 * @return	object
	 */
	final public function GetElement()
	{
		return $this->element;
	}

	/**
	 * Returns tag name as string
	 *
	 * @return	string
	 */
	final public function GetTag()
	{
		return $this->GetElement()->getName();
	}

	/**
	 * Sets new element
	 *
	 * @param SimpleXmlElement $el
	 * @return boolean
	 */
	final public function SetElement(\SimpleXmlElement $el)
	{
		$this->element = $el;
		return true;
	}

	/**
	 * Returns attribute value by name
	 *
	 * @param	string	$name
	 * @return	string
	 */
	final public function GetAttribute($name)
	{
		if($this->AttributeExists($name))
		//		if (isset($content[$param]))
		{
			$el = $this->GetElement();
			$res = (string)$el[$name];

			if (preg_match('~\(\$([a-z_0-9]+)\.([a-z_0-9]+)\)~i', $res, $found))
			{
				$res = core("Registry")->Get($found[2], $found[1]);
				//print $res."<br />";
			}
			elseif(is_numeric($res))
			{
				$res = (int)$res;
			}

			return $res;
		}
		else
		{
			service("debug")->error("Attribute $name not provided by comp " . $this->GetTag());
		}
	}

	/**
	 * Adds attribute to element
	 *
	 * @param	string	$tag
	 * @param	string	$value
	 * @return	boolean
	 */
	final public function SetAttribute($tag, $value)
	{
		$el = $this->GetElement();
		$el[$tag] = $value;

		return true;
	}


	/**
	 * Adds attribute to element
	 *
	 * @param       string  $tag
	 * @param       string  $value
	 * @return      boolean
	 */
	final public function AddAttribute($tag, $value, $overwrite = false)
	{
		$el = $this->GetElement();

		if (!empty($el[$tag]) && !$overwrite && true)
		{
			$content = $el[$tag];

			//Doubling value. No good anyway.
			if ($content == $value)
			{
				return true;
			}

			$contentArray = explode(" ", $content);

			//If this value absent from the values list -- add it
			if (!in_array($value, $contentArray) && !$overwrite)
			{
				$contentArray[] = $value;

				$content = implode(" ", $contentArray);

				$el[$tag] = $content;
			}
		}
		else
		{
			$el[$tag] = $value;
		}

		return true;
	}



	/**
	 * Adds array of attributes
	 *
	 * @see AddAttribute
	 * @param	array	$params
	 * @return	boolean
	 */
	final public function AddAttributes($params)
	{
		foreach ($params as $key=>$value)
		{
			$this->AddAttribute($key, $value);
		}

		return true;
	}

	final public function GetAttributes($filter = false)
	{
		$el = $this->GetElement();

		$attrs = $el->attributes();

		$res = array();

		foreach ($attrs as $key=>$item)
		{
			$res[(string)$key] = (string)$item;
		}

		if (!empty($filter) && is_array($filter))
		{
			$res = array_intersect_key($res, array_flip($filter));
		}

		return $res;
	}

	final public function AttributeExists($name)
	{
		$el = $this->GetElement();
		return isset($el[$name]);
	}

	/**
	 * Builds html-code from SimpleXml
	 *
	 * @return	string
	 */
	final public function Build()
	{
		$res = $this->GetElement()->asXml();

		//Warning! Govnokod! Gettting rid of ?xml?
		$res = preg_replace("~<\?.*\?>~i", "", $res);

		$res = trim(html_entity_decode($res));

		return $res;
	}

	/**
	 * Sets text content of the element
	 *
	 * @param	string	$content
	 * @return	boolean
	 */
	final public function SetContent($content)
	{
		$el = $this->GetElement();

		$el[0] = $content;
		return true;
	}

	final public function GetContent()
	{
		$el = $this->Getelement();

		return (string)$el;
	}

	/**
	 * Adds another element to this one as a child
	 *
	 * @param	HtmlElement $el
	 * @return	boolean
	 */
	final public function AddChild(HtmlElement $el)
	{
		$parent = dom_import_simplexml($this->GetElement());
		$child = dom_import_simplexml($el->GetElement());

		$child = $parent->ownerDocument->importNode($child, true);
		$parent->appendChild($child);

		return true;
	}

	/**
	 * Returns child element by tag name
	 *
	 * @param	string	$tag	Tag name
	 * @param	integer	$num	Number of child with this tag name
	 * @return	HtmlElement
	 */
	final public function GetChild($tag, $num = 0)
	{
		$child = new HtmlElement($tag);

		$parentElement = $this->GetElement()->{$tag}[$num];

		$child->SetElement($parentElement);
		return $child;
	}

	final public function GetChildren()
	{
		$el = $this->GetElement();

		$children = array();

		foreach ($el->children() as $item)
		{
			$children[] = new \core\HtmlElement($item);
		}

		return $children;
	}
}